package classreflex;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author 15594
 */
public class ClassTest {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
        Class<Person> personClass = Person.class;

        System.out.println("——————————————获取运行时类的对象————————————————");

        //通过newInstance()方法获取运行时类的对象
        Person person = personClass.newInstance();


        System.out.println("----------获取运行时对象的属性------------");

        //获取属性结构，getFields（）；获取当前运行时对象及其父类中声明为public的属性
        Field[] fields = personClass.getFields();

        for (Field field : fields) {
            System.out.println(field);
        }

        System.out.println("++++++++++");

        //返回包括公共、受保护、默认（包）访问和私有字段，但不包括继承的字段。
        Field[] declaredFields = personClass.getDeclaredFields();

        for (Field field : declaredFields) {
            System.out.println("获取属性的信息："+field);
            System.out.println("获取属性名："+field.getName());
            System.out.println("获取属性类型："+field.getType());
            System.out.println("获取属性修饰类型："+field.getModifiers());
            System.out.println("获取注解："+field.getAnnotations());
            System.out.println("----------------");
        }

        System.out.println("----------获取运行时类的封装类型为公共的注解------------");

        Annotation[] annotations = personClass.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }

        System.out.println("----------获取运行时类的封装类型为public的所有包括父类方法------------");


        Method[] methods = personClass.getMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
        }

        System.out.println("----------获取运行时类的所有方法（不包括父类）------------");
        Method[] declaredMethods = personClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName());
        }

        System.out.println("————————————————————-设置运行时类属性的值-------------");
        //方式一：设置pubic类型的属性，包括父类
        Field show = personClass.getField("show");
        show.set(person,"你好？");

        //方式二：设置运行时类的所有属性，不包括父类
        Field age = personClass.getDeclaredField("age");
        //强制修改私有属性
        age.setAccessible(true);
        //person指定将这个值赋值给哪个对象。如果是静态的属性，着为null
        age.set(person,123);
        System.out.println(age.get(person));

        System.out.println("person:"+person.toString());

        System.out.println("----------操作运行时类的方法——————————————");


        method();

    }

    private static void method() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class<Person> personClass = Person.class;
        Person person = personClass.newInstance();
        Method show = personClass.getDeclaredMethod("show", int.class, String.class);
        show.setAccessible(true);
        String str = (String)show.invoke(person, 1, "asd");
        System.out.println(str);
    }
}
